package com.javasm.commons.file;

import cn.hutool.core.io.IoUtil;
import com.javasm.commons.entity.AxiosResult;
import com.javasm.commons.enums.E;
import com.javasm.commons.exception.MvcException;
import com.javasm.util.OssUtil;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@RestController
public class FileHandler {
    @Value("${mvc.root}")
    private String root;

    //Map<String,MultipartFile>  :key:文件表单参数名, value:文件对象(文件名,大小,文件流)
    @PostMapping("upload")
    @SuppressWarnings("unchecked")//List没有使用泛型， .@SuppressWarnings("unchecked") 隐藏所有的不安全的警告信息
    public AxiosResult doUpload(MultipartFile myfile, MultipartFile jl) throws IOException {
        String originalFilename = myfile.getOriginalFilename();
        long size = myfile.getSize();
        //文件内容字节数组,小文件使用getBytes方法.一次性把InputStream流的数据读取到bytes数组
//        byte[] bytes = myfile.getBytes();
//        IOUtils.write(bytes,out);
        //大文件使用流来慢慢的读
        InputStream in = myfile.getInputStream();//文件内容,文件流
        //把文件存到指定的磁盘目录

        SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");
        String time=df.format(new Date());

        File file = new File(root+"/"+time);
        if(!file.exists())file.mkdirs();//创建多级文件夹

        String filepath = time+"/"+originalFilename;
        File target = new File(root,filepath);
        FileOutputStream out = new FileOutputStream(target);
        BufferedOutputStream bout = new BufferedOutputStream(out);
        byte[] bytes= new byte[2048];
        int r;
        while((r=in.read(bytes))!=-1){
            bout.write(bytes,0,r);
        }
        bout.flush();
        bout.close();

        //返回客户端什么数据?
        Map<String, Object> map  = new HashMap<>();
        map.put("real_name",originalFilename);
        map.put("file_size",size);
        map.put("file_path",filepath);
        map.put("upload_time", System.currentTimeMillis());
        return AxiosResult.suc(map);
    }

    //文件下载,返回值类型必须是ResponseEntity,因为文件下载必须指定content_disposition响应头
    @GetMapping("download")
    @SuppressWarnings("unchecked")//List没有使用泛型， .@SuppressWarnings("unchecked") 隐藏所有的不安全的警告信息
    public ResponseEntity doDownload(String filePath, String realName) throws Exception {
        File f = new File(root,filePath);
        if(!f.exists())
            throw new MvcException(E.NOT_EXISTS);

        byte[] bytes = IOUtils.toByteArray(new FileInputStream(f)); //文件转字节
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Disposition","attachment;filename="+ URLEncoder.encode(realName, "utf-8"));
        return new ResponseEntity(bytes,headers, HttpStatus.OK);
    }


    //将文件上传到阿里云oss云存储
    @PostMapping("uploadFileFromOss")
    public AxiosResult uploadFileFromOss(MultipartFile myfile) throws IOException {
        // 填写Bucket名称
        String bucketName = "mobie-eps";
        //文件名
        String originalFilename = myfile.getOriginalFilename();
        // 文件大小
        long size = myfile.getSize();

        //小文件上传
        byte[] bytes = myfile.getBytes();
        //大文件上传
//        InputStream in = myfile.getInputStream();

        //不能用服务器本地存储,使用云存储 原因 存储到阿里oss云存储 支持分布式部署，传统上传文件到本地服务器中，不支持分布式部署
        String objectName="eps/"+originalFilename;
        // 将文件上传到阿里云oss云存储
//        OssUtil.uploadToOss(bytes, bucketName,objectName);

        // 获取图片地址用来预览
        String url= OssUtil.uploadImg(bytes, bucketName,objectName);
        // 将上传文件到oss云存储数据封装给前端
        Map<String,Object> map = new HashMap<>();
        map.put("bucketName",bucketName);
        map.put("objectName",objectName);
        map.put("size",size);
        map.put("fileName",originalFilename);
        map.put("url",url);
        return AxiosResult.suc(map);
    }

    //从oss云存储下载文件
    @GetMapping("downloadFileFromOss")
    public ResponseEntity downloadFileFromOss(String bucketName,String objectName,String fileName) throws IOException {
        InputStream in = OssUtil.download(bucketName, objectName);
        // hutool组件工具类 读取流数据到字节数组
        byte[] bytes = IoUtil.readBytes(in);
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Disposition","attachment;filename="+ URLEncoder.encode(fileName, "utf-8"));
        return new ResponseEntity(bytes,headers, HttpStatus.OK);// 将字节数据返回给前端
    }
    // 从oss云存储删除文件
    @GetMapping("deleteFile")
    public AxiosResult deleteFile(String bucketName,String objectName) throws IOException {
        OssUtil.delFile(bucketName,objectName);
        return AxiosResult.suc();
    }
}
